import React, { useEffect, useState } from 'react'
import { Form, message } from 'antd'
import { cloneDeep } from 'lodash'
import moment from 'moment'
import { useNavigate } from 'react-router-dom'
import { useRecoilValue } from 'recoil'
import {
  IReport,
  IVariable,
  IEvent,
  IBasic,
  ITYPE,
  ITargetList,
  ITarget,
  IEventTable,
  IImportVariable,
  IImportEvent,
} from '../type'
import {
  getVariableList,
  getEventList,
  getComputedTarget,
  temporaryHandle,
  getTemplate,
  submitHandle,
  getWard,
  updateOrAdd,
  deleteEvent,
} from '../service'
import { isNullData, getUrlParams, exportData, isSuccess } from '@/utils'
import { IVariableSort, IVariableSubmit, IPressure, IVariableItem } from '@/@types/common'
import { userInfo } from '@/store/userInfo'

export default (): IReport => {
  const navigate = useNavigate()
  const dataId = getUrlParams('id')
  const onlyLook = getUrlParams('onlyLook')
  // 用户信息
  const userMsg = useRecoilValue(userInfo)
  // 变量列表
  const [variableList, setVariableList] = useState<IVariableSort[]>([])
  // 保存基础信息
  const [basicMsg, setBasicMsg] = useState<IBasic>()
  // 变量和指标选项控制
  const [varTargetType, setVarTargetType] = useState<ITYPE>(ITYPE.VARIABLE)
  // 事件列表
  const [eventList, setEventList] = useState<IPressure[]>([])
  // 当前查看的事件
  const [curLookEvent, setCurLookEvent] = useState<IPressure>()
  // 变量表的form实例
  const [variableForm] = Form.useForm()
  // 存放计算后的指标内容
  const [targetList, setTargetList] = useState<ITargetList[]>([])
  // 存放动态指标季度表头名
  const [tableHeader, setTableHeader] = useState<string[]>([])
  // 控制事件添加弹窗的展示和因此
  const [showEventModal, setShowEventModal] = useState<boolean>(false)
  // 只读控制
  const [readonly, setReadOnly] = useState<boolean>(false)
  // 是否需要请求压疮数据接口
  const [needGetPressure, setNeedGetPressure] = useState<boolean>(false)
  // 变量表格导入的内容保存
  const [importVariable, setImportVariable] = useState<IVariableSubmit[]>([])
  // 平铺所有变量分类中的变量
  const [variableTiled, setVariableTiled] = useState<IVariableItem[]>([])
  // 保存变量form中的内容
  const [variableFormValue, setVariableFormValue] = useState<{ [name: string]: any }>()
  // 二次确认弹窗的展示和隐藏
  const [showCheckTarget, setShowCheckTarget] = useState<boolean>(false)
  // loading
  const [loading, setLoading] = useState<boolean>(false)
  // 事件loading
  const [eventLoading, setEventLoading] = useState<boolean>(false)
  // 病区级联
  const [wardList, setWardList] = useState<any[]>([])
  // 查看状态
  const [isView, setIsView] = useState<boolean>(false)
  // 压疮病例数变量id, 该变量的数量要和底部事件
  const [pressureId, setPressureId] = useState<string>('')

  // 事件添加的form实例
  const [eventForm] = Form.useForm()

  // 修改指标类型
  const variableTargetChange = async (value: ITYPE) => {
    const formValue = await variableForm.validateFields()
    if (value === ITYPE.TARGET) {
      setVariableFormValue(formValue)
    }
    setVarTargetType(value)
  }

  // 获取事件数据内容
  const getEventData = async () => {
    const params = {
      dataId,
    }
    setEventLoading(true)
    const res = await getEventList(params)
    setEventLoading(false)
    if (isNullData(res) && res.data) {
      setEventList(res.data)
    }
  }

  // 将后端的IVariableSubmit改为key:value的格式
  const washImport2Form = (data: IVariableSubmit[]) =>
    data.reduce((obj, item) => {
      obj[item.variableId] = item.variableValue
      return obj
    }, {})

  // 初始化form
  const initForm = (value: IVariableSort[]) => {
    const tiled = value.flatMap((item) => item.variablePlatformVos)
    setVariableTiled(tiled)
    return tiled.reduce((obj, item) => {
      obj[item.id] = item.variableValue
      return obj
    }, {})
  }

  // 递归函数，将原始数据转换为 Cascader 数据结构
  const transformDataCatalogue = (items: any) =>
    items.map((item: any) => {
      const dis = item.type === '20' && item.endemicAreaVos.length === 0
      const cascaderItem: any = {
        label: item.unit,
        value: item.id.toString(),
        disabled: dis,
      }
      if (item.endemicAreaVos.length > 0) {
        cascaderItem.children = transformDataCatalogue(item.endemicAreaVos)
      }
      return cascaderItem
    })

  // 获取病区级联
  const getWardHandle = async () => {
    const params = {
      hospitalCode: userMsg.hospitalCode,
    }
    const res = await getWard(params)
    if (isNullData(res) && res.data) {
      setWardList(transformDataCatalogue(res.data.endemicAreaVos))
    }
  }

  // 获取变量数据内容
  const getVariableListHandle = async () => {
    const params = {
      dataId,
    }
    setLoading(true)
    const res = await getVariableList(params)
    setLoading(false)
    if (isNullData(res) && res.data) {
      if (res.data.sortPlatformVos) {
        setVariableList(res.data.sortPlatformVos)
        variableForm.setFieldsValue(initForm(res.data.sortPlatformVos))
      }
      setBasicMsg(res.data.dataReportVo)
      setNeedGetPressure(res.data.flag)
      // await getWardHandle()
      if (res.data.flag) {
        // 保存压疮变量的id
        setPressureId(res.data.pressureId)
        // 获取病区级联
        await getWardHandle()
        // 获取事件
        await getEventData()
      }
    }
  }

  // 将form中的变量转为可以提交的格式
  const washVariable = (data: { [name: string]: any }) => {
    const result = []
    for (const key in data) {
      const value = data[key]
      const curVariable = variableTiled.find((item) => item.id === key)
      if (value !== undefined) {
        result.push({
          variableId: key,
          variableValue: value,
          id: curVariable?.variableValueId,
        })
      }
    }
    return result
  }

  // 根据当前变量获取计算后的指标
  const getTargetByVariable = async () => {
    let params
    if (varTargetType === ITYPE.TARGET && variableFormValue) {
      const variableValueDtos = washVariable(variableFormValue)
      params = {
        dataId,
        variableValueDtos,
        injuryInformationDtos: eventList.map((item) => ({
          ...item,
        })),
      }
    } else {
      const formValue = await variableForm.validateFields()
      const variableValueDtos = washVariable(formValue)
      params = {
        dataId,
        variableValueDtos,
        injuryInformationDtos: eventList,
      }
    }
    setLoading(true)
    const res = await getComputedTarget(params)
    setLoading(false)
    if (isNullData(res) && res.data) {
      setTargetList(res.data.targetValueVos)
      setTableHeader(res.data.dataQuarter)
    }
  }

  // 关闭回调
  const closeHandle = () => {
    setShowEventModal(false)
    eventForm.resetFields()
    if (curLookEvent) {
      setCurLookEvent(undefined)
    }
  }

  // 导入新增压疮
  const addPressure = (value: IPressure[]) => {
    for (const item of value) {
      const formatValue = {
        ...item,
        happenDate: item.happenDate,
        admissionTime: item.admissionTime,
      }
      const eventArr = cloneDeep(eventList)
      // 判断病历号是否重复
      const alreadyHasIndex = eventArr.findIndex((item) => item.patientNumber === value.patientNumber)
      if (alreadyHasIndex > -1) {
        eventArr.splice(alreadyHasIndex, 1, formatValue)
      } else {
        eventArr.push(formatValue)
      }
      setEventList(eventArr)
    }
  }

  /**
   * @description 添加事件弹窗确认回调
   * @param {boolean} needClose
   */
  const onOkHandle = (needClose: boolean) => {
    eventForm.validateFields().then(async (value) => {
      const formatValue = {
        ...value,
        happenDate: value.happenDate.format('YYYY-MM-DD'),
        admissionTime: value.admissionTime.format('YYYY-MM-DD'),
        happenArea: value.happenArea.at(-1),
      }
      if (isView) {
        const params = {
          dataId,
          injuryInformationDtos: [{ ...formatValue, id: curLookEvent?.id }],
        }
        const res = await updateOrAdd(params)
        if (isNullData(res) && isSuccess(res.data)) {
          // 获取事件
          await getEventData()
        } else {
          message.error(res.data.message || '编辑失败')
          return
        }
      } else {
        const params = {
          dataId,
          injuryInformationDtos: [formatValue],
        }
        const res = await updateOrAdd(params)
        if (isNullData(res) && isSuccess(res.data)) {
          // 获取事件
          await getEventData()
        } else {
          message.error(res.data.message || '新增失败')
          return
        }
      }
      if (needClose) {
        // 如果需要关闭弹窗则代表直接点击的确认
        closeHandle()
      } else {
        // 属于要继续添加
        eventForm.resetFields()
      }
    })
  }

  // 删除回调
  const deleteHandle = async (record: IPressure) => {
    const params = {
      id: record.id,
    }
    const res = await deleteEvent(params)
    if (isNullData(res)) {
      await getEventData()
    } else {
      message.error('删除失败')
    }
  }

  // 校验压疮数量和底部表格数量是否一致
  const checkFormAndTable = () => {
    for (const item of variableList) {
      const curPressure = item.variablePlatformVos.find((child) => child.id === pressureId)
      if (curPressure) {
        const formPressure = variableForm.getFieldValue(curPressure.id)
        if (Number(formPressure) !== eventList.length) {
          message.error('压疮变量内容和对应的事件内容病例数不匹配')
          return false
        }
        return true
      }
    }
  }

  // 暂存确认回调
  const temporaryStorage = async () => {
    const formValue = varTargetType === ITYPE.TARGET ? variableFormValue : await variableForm.validateFields()
    if (formValue) {
      const variableValueDtos = washVariable(formValue)
      const params = {
        dataId,
        variableValueDtos,
        // injuryInformationDtos: eventList,
      }
      const res = await temporaryHandle(params)
      if (isNullData(res)) {
        message.success('暂存成功')
      }
    }
  }

  // 获取模板
  const getTemplateHandle = async () => {
    const params = {
      id: dataId,
    }
    const res = await getTemplate(params)
    if (res) {
      exportData(res, `变量模板-${dataId}`, 'xlsx')
    }
  }

  // 提交按钮点击事件
  const submitBtnHandle = async () => {
    await variableForm.validateFields()
    await getTargetByVariable()
    setShowCheckTarget(true)
  }

  // 提交回调
  const submitVerify = async () => {
    const canPass = checkFormAndTable()
    if (!canPass && canPass !== undefined) return
    const formValue = varTargetType === ITYPE.TARGET ? variableFormValue : await variableForm.validateFields()
    if (formValue) {
      const variableValueDtos = washVariable(formValue)
      const params = {
        dataId,
        variableValueDtos,
        // injuryInformationDtos: eventList.map((item) => ({
        //   ...item,
        // })),
      }
      const res = await submitHandle(params)
      if (isNullData(res)) {
        message.success('已提交')
        navigate('/data-filling')
      }
    }
  }

  const findParent: any = (data: any, targetValue: string, parentIds: any = []) => {
    for (let i = 0; i < data.length; i++) {
      const node = data[i]

      if (node.value === targetValue) {
        return [...parentIds, node.value]
      }

      if (node.children) {
        const ids = findParent(node.children, targetValue, [...parentIds, node.value])
        if (ids) {
          return ids
        }
      }
    }

    return null
  }

  // 事件查看回调
  const eventLookHandle = (record: IPressure) => {
    setIsView(true)
    setCurLookEvent(record)
    setShowEventModal(true)
    const happenArea = findParent(wardList, record.happenArea)
    eventForm.setFieldsValue({
      ...record,
      happenDate: moment(record.happenDate),
      admissionTime: moment(record.admissionTime),
      happenArea,
    })
  }

  // 导入成功后回调
  const importSuccess = async () => {
    await getEventData()
  }

  const init = async () => {
    setReadOnly(Number(onlyLook) === 1)
    await getVariableListHandle()
  }
  // 给变量组件的参数
  const variableParams: IVariable = {
    variableList,
    formObj: variableForm,
    readonly,
  }

  // 给事件内容的参数
  const eventParams: IEvent = {
    eventList,
    eventLookHandle,
    loading: eventLoading,
    deleteHandle,
    readonly,
  }

  // 给指标组件的参数
  const targetParams: ITarget = {
    targetList,
    tableHeader,
    loading,
  }

  // 给事件弹窗的参数
  const eventTableParams: IEventTable = {
    formObj: eventForm,
    handleOk: onOkHandle,
    handleCancel: closeHandle,
    visible: showEventModal,
    onlyLook: readonly,
    wardList,
    isEdit: !!curLookEvent,
  }

  // 给变量导入组件的参数
  const importVariableParams: IImportVariable = {
    id: dataId,
    setImportVariable,
  }

  // 给事件导入组件的参数
  const importEventParams: IImportEvent = {
    id: dataId,
    importSuccess,
  }

  useEffect(() => {
    if (varTargetType === ITYPE.TARGET && variableFormValue) {
      getTargetByVariable()
    }
  }, [varTargetType, variableFormValue])

  useEffect(() => {
    init()
  }, [])

  useEffect(() => {
    // 导入变量后覆盖form的内容
    variableForm.setFieldsValue(washImport2Form(importVariable))
  }, [importVariable])

  return {
    variableParams,
    eventParams,
    basicMsg,
    varTargetType,
    variableTargetChange,
    targetParams,
    eventTableParams,
    temporaryStorage,
    submitVerify,
    getTemplateHandle,
    setShowEventModal,
    importVariableParams,
    importEventParams,
    showCheckTarget,
    readonly,
    submitBtnHandle,
    setShowCheckTarget,
    needGetPressure,
    setIsView,
  }
}
